package com.ruoyi.ruoyiqywechat.service.qywechat.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.ruoyi.common.qy.config.CrmebConfig;
import com.ruoyi.common.qy.constants.SysConfigConstants;
import com.ruoyi.common.qy.constants.UploadConstants;
import com.ruoyi.common.qy.domain.SystemAttachment;
import com.ruoyi.common.qy.exception.CrmebException;
import com.ruoyi.common.qy.oss.OssService;
import com.ruoyi.common.qy.result.CommonResultCode;
import com.ruoyi.common.qy.utils.CrmebUtil;
import com.ruoyi.common.qy.utils.UploadUtil;
import com.ruoyi.common.qy.vo.CloudVo;
import com.ruoyi.common.qy.vo.FileResultVo;
import com.ruoyi.ruoyiqywechat.service.SystemConfigService;
import com.ruoyi.ruoyiqywechat.service.qywechat.SystemAttachmentService;
import com.ruoyi.ruoyiqywechat.service.qywechat.UploadService;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

@Service
public class UploadServiceImpl implements UploadService {
    @Autowired
    private SystemConfigService systemConfigService;
    @Autowired
    private CrmebConfig crmebConfig;
    @Override
    public FileResultVo imageUpload(MultipartFile multipartFile, String model, Integer pid) {
        FileResultVo fileResultVo = new FileResultVo();
        try {
            fileResultVo = commonUpload(multipartFile, model, pid, UploadConstants.UPLOAD_FILE_KEYWORD);
        } catch (IOException e) {
            throw new CrmebException("图片上传 IO异常");
        }
        return fileResultVo;
    }
    /**
     * 上传校验
     *
     * @param fileName 文件名称
     * @param fileSize 文件大小
     * @return 后缀名
     */
    private String uploadValidate(String fileName, float fileSize, String fileType, String contentType) {
        // 文件后缀名
        String extName = FilenameUtils.getExtension(fileName).toLowerCase();
        if (StrUtil.isEmpty(extName)) {
            if (StrUtil.isNotBlank(contentType)) {
                extName = contentType.split("/")[1];
            } else {
                throw new CrmebException(CommonResultCode.VALIDATE_FAILED, "文件类型未定义，无法上传...");
            }
        }

        String extStr = systemConfigService.getValueByKey(fileType.equals(UploadConstants.UPLOAD_AFTER_FILE_KEYWORD) ? SysConfigConstants.UPLOAD_FILE_EXT_STR_CONFIG_KEY : SysConfigConstants.UPLOAD_IMAGE_EXT_STR_CONFIG_KEY);
        // 判断文件的后缀名是否符合规则
        if (StrUtil.isNotBlank(extStr)) {
            // 切割文件扩展名
            List<String> extensionList = CrmebUtil.stringToArrayStr(extStr);
            if (CollUtil.isNotEmpty(extensionList)) {
                //判断
                if (!extensionList.contains(extName)) {
                    throw new CrmebException(CommonResultCode.VALIDATE_FAILED, "上载文件类型只能为：" + extStr);
                }
            } else {
                throw new CrmebException(CommonResultCode.VALIDATE_FAILED, "上载文件类型只能为：" + extStr);
            }
        }
        // 文件大小验证
        int size = Integer.parseInt(systemConfigService.getValueByKey(fileType.equals(UploadConstants.UPLOAD_AFTER_FILE_KEYWORD) ? SysConfigConstants.UPLOAD_FILE_MAX_SIZE_CONFIG_KEY : SysConfigConstants.UPLOAD_IMAGE_MAX_SIZE_CONFIG_KEY));
        String fs = String.format("%.2f", fileSize);
        if (fileSize > size) {
            throw new CrmebException(CommonResultCode.VALIDATE_FAILED, StrUtil.format("最大允许上传 {} MB文件，当前文件大小为 {} MB", size, fs));
        }
        return extName;
    }

    @Autowired
    private SystemAttachmentService systemAttachmentService;
    /**
     * 公共上传
     *
     * @param multipartFile 文件
     * @param model         模块 用户user,商品product,微信wechat,文章article,系统system
     * @param pid           分类ID 0编辑器,1商品图片,2拼团图片,3砍价图片,4秒杀图片,5文章图片,6组合数据图,7前台用户,8微信系列
     * @param fileType      文件类型
     * @return FileResultVo
     * @throws IOException IOE异常
     */
    private FileResultVo commonUpload(MultipartFile multipartFile, String model, Integer pid, String fileType) throws IOException {
        if (ObjectUtil.isNull(multipartFile) || multipartFile.isEmpty()) {
            throw new CrmebException(CommonResultCode.VALIDATE_FAILED, "上载的文件对象不存在...");
        }
        // 校验
        String fileName = multipartFile.getOriginalFilename();
        float fileSize = (float) multipartFile.getSize() / 1024 / 1024;
        // 文件后缀名
        String extName = uploadValidate(fileName, fileSize, fileType, multipartFile.getContentType());
        if (fileName.length() > 99) {
            fileName = StrUtil.subPre(fileName, 90).concat(".").concat(extName);
        }

        // 服务器存储地址
        String rootPath = crmebConfig.getImagePath().trim();
        // 模块
        String modelPath = "public/" + model + "/";
        // 类型
        String type = (fileType.equals(UploadConstants.UPLOAD_FILE_KEYWORD) ? UploadConstants.UPLOAD_FILE_KEYWORD : UploadConstants.UPLOAD_AFTER_FILE_KEYWORD) + "/";

        // 变更文件名
        String newFileName = UploadUtil.fileName(extName);
        // 创建目标文件的名称，规则：  子目录/年/月/日.后缀名
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd");
        String format = simpleDateFormat.format(new Date());
        String webPath = type + modelPath + format + "/";
        // 文件分隔符转化为当前系统的格式
        String destPath = FilenameUtils.separatorsToSystem(rootPath + webPath) + newFileName;
        // 创建文件
        File file = UploadUtil.createFile(destPath);

        // 拼装返回的数据
        FileResultVo resultFile = new FileResultVo();
        resultFile.setFileSize(multipartFile.getSize());
        resultFile.setFileName(fileName);
        resultFile.setExtName(extName);
        resultFile.setUrl(webPath + newFileName);
        resultFile.setType(multipartFile.getContentType());
        if (fileType.equals(UploadConstants.UPLOAD_FILE_KEYWORD)) {
            resultFile.setType(resultFile.getType().replace("image/", ""));
        } else {
            resultFile.setType(resultFile.getType().replace("file/", ""));
        }

        SystemAttachment systemAttachment = new SystemAttachment();
        systemAttachment.setName(resultFile.getFileName());
        systemAttachment.setSattDir(resultFile.getUrl());
        systemAttachment.setAttSize(resultFile.getFileSize().toString());
        systemAttachment.setAttType(resultFile.getType());
        systemAttachment.setImageType(1);   //图片上传类型 1本地 2七牛云 3OSS 4COS, 默认本地
        systemAttachment.setPid(pid);

        //图片上传类型 1本地 2七牛云 3OSS 4COS, 默认本地
        String uploadType = systemConfigService.getValueByKeyException(SysConfigConstants.CONFIG_UPLOAD_TYPE);
        Integer uploadTypeInt = Integer.parseInt(uploadType);
        if (uploadTypeInt.equals(1)) {
            // 保存文件
            multipartFile.transferTo(file);
            systemAttachmentService.save(systemAttachment);
            return resultFile;
        }
        CloudVo cloudVo = new CloudVo();
        // 判断是否保存本地
        String fileIsSave = systemConfigService.getValueByKeyException(SysConfigConstants.CONFIG_FILE_IS_SAVE);
        multipartFile.transferTo(file);
        switch (uploadTypeInt) {
            case 3:
                systemAttachment.setImageType(3);
                cloudVo.setDomain(systemConfigService.getValueByKeyException(SysConfigConstants.CONFIG_TX_UPLOAD_URL));
                cloudVo.setAccessKey(systemConfigService.getValueByKeyException(SysConfigConstants.CONFIG_TX_ACCESS_KEY));
                cloudVo.setSecretKey(systemConfigService.getValueByKeyException(SysConfigConstants.CONFIG_TX_SECRET_KEY));
                cloudVo.setBucketName(systemConfigService.getValueByKeyException(SysConfigConstants.CONFIG_TX_STORAGE_NAME));
                cloudVo.setRegion(systemConfigService.getValueByKeyException(SysConfigConstants.CONFIG_TX_STORAGE_REGION));
                try {
                    String webPathTx = crmebConfig.getImagePath();
                    String string = OssService.uploadFile(multipartFile,format + "/"+newFileName);
                    resultFile.setUrl(string);
                    systemAttachment.setAttDir(string);
                } catch (Exception e) {
                }
                break;
        }
        systemAttachmentService.save(systemAttachment);
        if (!fileIsSave.equals("1")) {
            // 删除本地文件
            file.delete();
        }
        return resultFile;
    }
}
